#ifndef _THREAD_TOOL_H_
#define _THREAD_TOOL_H_

#include<iostream>
#include<pthread.h>
#include<queue>
#include<ctime>
#include<cstdlib>
#include<deque>
#include<memory>  
#define NUM 5
using namespace std;

template<class T>
class ThreadPool
{
public:
    ThreadPool(int cap = NUM) : thread_num(cap)
    {
        pthread_mutex_init(&_lock, nullptr);
        pthread_cond_init(&_cond, nullptr);
    }

    void LockQueue()
    {
        pthread_mutex_lock(&_lock);
    }

    void UnlockQueue()
    {
        pthread_mutex_unlock(&_lock);
    }

    void Wait()
    {
        pthread_cond_wait(&_cond, &_lock);
    }

    void Wake()
    {
        pthread_cond_signal(&_cond);
    }

    bool isQueueEmpty()
    {
        return _task_queue.size() == 0 ? true : false;
    }

    static void* Rountine(void *arg)
    {
        pthread_detach(pthread_self());
        ThreadPool* self = (ThreadPool*)arg;

        while (true)
        {
            self->LockQueue();
            while (self->isQueueEmpty()) //避免被虚假唤醒
            {
                self->Wait();
            }

            std::unique_ptr<T> t;
            self->Pop(t);
            self->UnlockQueue();

            // 执行任务
            t->run();
        }
    }

    void Thread_pool_init()
    {
        pthread_t tids[thread_num];

        for (int i = 0; i < thread_num; i++)
        {
            pthread_create(&tids[i], nullptr, Rountine, this);
        }
    }

    void push(std::unique_ptr<T>&& in)
    {
        LockQueue();
        _task_queue.push_back(std::move(in));  // 使用 move 将任务指针传入队列
        Wake();
        UnlockQueue();
    }

    // Pop 时返回 unique_ptr<T> 类型的任务指针
    void Pop(std::unique_ptr<T>& out)
    {
        out = std::move(_task_queue.front());
        _task_queue.pop_front();
    }

    ~ThreadPool()
    {
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
    }

private:
    pthread_mutex_t _lock;
    pthread_cond_t _cond;
    deque<std::unique_ptr<T>> _task_queue;  // 存储智能指针
    int thread_num;
};

#endif
